package dir.simulation;

import java.io.IOException;
import java.util.Vector;

import dht.data.Access;
import dht.data.FileAccessGenerator;
import dht.data.NetworkUtil;
import dht.simulation.DhtException;
import dht.simulation.GlobalVariables;
import dht.statistics.DhtStatistics;
import dse.IOUtil;
import dse.modules.eln.EarthLikeNetwork;

public class DirSimulator {
	protected EarthLikeNetwork network;

	public void runSimulator(String topologyFile) throws IOException,
			DhtException {
		int lambdaR = GlobalVariables.lambdaR, lambdaW = GlobalVariables.lambdaW;
		double totalTime = GlobalVariables.secondPerPerid;
		int period = GlobalVariables.period;
		int fileNumber = GlobalVariables.fileNumber;

		long begin = System.currentTimeMillis();
		network = IOUtil.NetworkFromFile(topologyFile);
		System.out.println("EarthLikeNetwork init time: "
				+ (System.currentTimeMillis() - begin) + "ms");

		begin = System.currentTimeMillis();
		DirFs dir = new DirFs(network);
		System.out.println("DirFs init time: "
				+ (System.currentTimeMillis() - begin) + "ms");

		DhtStatistics.initialize(network.maxNodeId());

		begin = System.currentTimeMillis();
		NetworkUtil.initialize(network);
		System.out.println("NetworkUtil init time: "
				+ (System.currentTimeMillis() - begin) + "ms");

		begin = System.currentTimeMillis();
		FileAccessGenerator fileAccess = new FileAccessGenerator(fileNumber);
		System.out.println("FileAccessGenerator init time: "
				+ (System.currentTimeMillis() - begin) + "ms");
		for (int i = 1; i <= period; ++i) {
			begin = System.currentTimeMillis();
			Vector<Access> accesses = fileAccess.generate(network, lambdaR,
					lambdaW, totalTime);
			System.out.println(accesses.size() + " accesses added in period "
					+ i);
			for (Access access : accesses) {
				dir.addAccess(access);
			}
			dir.run(totalTime * i, false);
			System.out.println("Period " + i + " run time: "
					+ (System.currentTimeMillis() - begin) + "ms");
		}
		begin = System.currentTimeMillis();
		dir.run(totalTime * period + GlobalVariables.additionalSeconds, true);
		System.out.println("Additional period run time: "
				+ (System.currentTimeMillis() - begin) + "ms");

		DhtStatistics.dump();

		if (dir.totalAccess != dir.totalAccessProcessed) {
			System.out
					.println("totalAccess and totalAccessProcess don't match: "
							+ dir.totalAccess + " " + dir.totalAccessProcessed);
			for (Access access : dir.pendingAccesses.values()) {
				access.dump();
			}
			// throw new DhtException(
			// "totalAccess and totalAccessProcess don't match");
		} else {

		}
	}

	public static void main(String[] args) throws Exception {
		GlobalVariables.initialize("global.properties");

		DirSimulator simulator = new DirSimulator();

		long begin = System.currentTimeMillis();
		simulator.runSimulator(GlobalVariables.networkFile);
		System.out.println("Simulator run time: "
				+ (System.currentTimeMillis() - begin) + "ms");
	}

}
